package myJs.user.mission

import myJs.Utils._

import scala.scalajs.js.Dynamic.{global => g}
import myJs.tool.Tool
import myJs.tool.Tool._
import org.scalajs.dom.ext.Ajax
import scalatags.Text.all._
import myJs.myPkg.jquery._
import myJs.Implicits._
import myJs.myPkg.{ColumnOptions, ColumnOptionsBuilder, ExportOptions, TableOptions}
import org.scalajs.dom.{Element, document}

import scala.collection.immutable.SeqMap
import scala.scalajs.js.JSON
import scala.scalajs.js
import scala.scalajs.js.JSConverters._
import myJs.myPkg.bootstrap.Bootstrap.default._
import shared.Pojo.GroupDataKind
import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._
import myJs.Implicits._

/** Created by yz on 14/8/2020
  */
trait MissionResult {

  val tableId = "table"
  val modalId = "viewModal"

  def registerEvent = {
    $(document.body).on(
      "click",
      ".myViewFile",
      "",
      (y: Element) => {
        val fileName = $(y).dataValue
        viewFile(fileName)
      }
    )
    $(document.body).on(
      "click",
      ".myToggle",
      "",
      (y: Element) => {
        val tabJq = $(y).parents(".tab-pane")
        Tool.myToggle(tabJq)
      }
    )
  }

  def viewFile(fileName: String) = {
    refreshData(fileName).map { x =>
      $(s"#${modalId} #fileName").text(fileName)
      $(s"#${modalId}").modal("show")
    }
  }

  def getFilesExistInfo(fileNames: js.Array[String]) = {
    val fileExistInfoUrl = g.jsRoutes.controllers.MissionController.getFileNamesExistInfo().url.toString
    val dict = js.Dictionary("fileNames" -> fileNames)
    val data = JSON.stringify(dict)
    Ajax.post(url = s"${fileExistInfoUrl}", data = data, headers = Map("Content-Type" -> "application/json")).map {
      xhr =>
        xhr.responseText.toJDB
    }
  }

  def refreshMissionInfo(missionId: String) = {
    val url = g.jsRoutes.controllers.MissionController.getMissionById().url.toString
    Ajax.get(url = s"${url.noCache}&missionId=${missionId}").map { xhr =>
      val dict = JSON.parse(xhr.responseText).toJDJAn
      val fileNames = dict("input").toJArS
      getFilesExistInfo(fileNames).map { infoDict =>
        dict.foreach { case (k, v) =>
          val trueV = k match {
            case "kind" => Tool.getKindA(v.toString).render
            case "state" => Tool.successA.render
            case "input" =>
              val vs = v.toJArS
              vs.map { v =>
                if (infoDict(v)) {
                  val names = v.split("/")
                  val url = Tool.getDetailUrl(names(0))
                  a(href := s"${url}?fileName=${v.encodeURI}", target := "_blank", s"${v}")
                } else {
                  span(v)
                }
              }.mkString("&nbsp;&nbsp;")
            case x if x != "arg" => span(v.toString).render
            case x if x == "arg" => span().render
          }
          $(s"#mission #${k}").html(trueV)
          refreshArg(dict("arg"))
        }
      }
    }
  }

  def refreshArg(arg: js.Any) = {
    val tableId = "argTable"
    val columnNames = List(messages("parameter"), messages("value"))
    val columns = columnNames.map { columnName =>
      val fmt = columnName
      ColumnOptions.field(columnName).title(columnName).sortable(true)
    }.toJSArray
    val array = arg.toJDS.map { case (k, v) =>
      js.Dictionary(messages("parameter") -> k, messages("value") -> v)
    }.toJSArray
    val options = TableOptions.data(array).columns(columns).pagination(false)
    $(s"#${tableId}").bootstrapTable(options)
    if (array.isEmpty) {
      $("#arg").text(messages("none")).show()
      $(s"#${tableId}").hide()
    }
  }

  lazy val operateColumn = js.Array(
    ColumnOptions.field("operate").title(messages("operations")).formatter(operateFmt).filterControl("clear")
  )

  def operateFmt: js.Function = { (v: js.Any, row: js.Dictionary[js.Any]) =>
    val fileRelPath = if (row.myGet("fileRelPath").trim.isEmpty) "" else s"${row("fileRelPath")}/"
    val downloadUrl = g.jsRoutes.controllers.MissionController.downloadResultFile().url.toString
    val downloadStr = a(
      title := messages("download"),
      href := s"${downloadUrl}?missionId=${getMissionId}&fileName=${fileRelPath}${row("fileName")}",
      cursor.pointer,
      span(em(cls := "fa fa-download"))
    )

    val detailViewStr = a(
      title := messages("viewDetails"),
      `class` := "myViewFile",
      dataValue := s"${fileRelPath}${row("fileName")}",
      span(em(cls := "fa fa-eye"))
    )

    val rs = if (List(".pdf", ".zip", ".svg", ".json").exists(x => row("fileName").toString.endsWith(x))) {
      List(downloadStr)
    } else List(detailViewStr, downloadStr)
    rs.mkString("&nbsp;")
  }

  def refreshFileInfo(missionId: String) = {
    val url = g.jsRoutes.controllers.MissionController.getResultFileInfo().url.toString
    Ajax.get(url = s"${url.noCache}&missionId=${missionId}", headers = Map("Content-Type" -> "application/json")).map {
      xhr =>
        val rs = xhr.responseText.toJDJAn
        val headerMap =
          SeqMap("fileName" -> messages("file"), "rowNum" -> messages("rowsInDataFile"), "intro" -> messages("note"))
        val columnNames = headerMap.keyList
        val columns = columnNames
          .map { columnName =>
            val fmt = columnName
            val title = headerMap.getOrElse(columnName, columnName)
            ColumnOptions.field(columnName).title(title).sortable(true)
          }
          .toJSArray
          .concat(operateColumn)
        val options = TableOptions.data(rs).columns(columns).pagination(false)
        $(s"#${tableId}").bootstrapTable(options)
    }
  }

  def cellView(json: js.Dictionary[js.Any], row: js.Dictionary[js.Any]) = {
    val color = json.myGet("color")
    val v = json.myGet("value")
    val bgColor = if (color.nonBlank) {
      s"#${color.drop(2)}"
    } else {
      "white"
    }
    div(
      width := "100%",
      height := 40,
      backgroundColor := bgColor,
      div(
        paddingLeft := 8,
        paddingRight := 8,
        paddingTop := 10,
        paddingBottom := 10,
        v
      )
    )
  }

  def expFmt(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[js.Any]) =>
    columnName match {
      case x if x == "0" =>
        val json = v.asInstanceOf[js.Dictionary[js.Any]]
        val str = json.myGet("value")
        span(
          str
        )
      case otherName =>
        val json = v.asInstanceOf[js.Dictionary[js.Any]]
        val html = cellView(json, row)
        html
    }

  def expStyle(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[Any]) =>
    columnName match {
      case x if x == "0" =>
        js.Dictionary()
      case _ =>
        js.Dictionary(
          "css" -> js.Dictionary(
            "padding" -> 0
          )
        )
    }

  def refreshData(fileName: String) = {
    val url = g.jsRoutes.controllers.MissionController.getFileData().url.toString
    Ajax
      .get(
        url = s"${url.noCache}&missionId=${getMissionId}&fileName=${fileName}",
        headers = Map("Content-Type" -> "application/json")
      )
      .map { xhr =>
        val rs = xhr.responseText.toJDJAn
        val columnNames = rs("columnNames").toJArS
        val array = rs("array").toJArJDS
        val columns = if (array.nonEmpty) {
          val ts=array.head.keys.toList.map { index =>
            fileName.fileNameSuffix match {
              case "xlsx" =>
                val fmt = expFmt(index)
                val style = expStyle(index)
                val basicOptions = ColumnOptions.field(index).sortable(true).cellStyle(style).formatter(fmt)
                if (columnNames.isEmpty) {
                  basicOptions.title(index)
                } else {
                  val columnName = columnNames(index.toInt)
                  basicOptions.title(columnName)
                }
              case _ =>
                val basicOptions = ColumnOptions.field(index).sortable(true)
                if (columnNames.isEmpty) {
                  basicOptions.title(index)
                } else {
                  val columnName = columnNames(index.toInt)
                  basicOptions.title(columnName)
                }
            }
          }.toJSArray
          ts
        } else js.Array[ColumnOptionsBuilder]()
        val exportOptions = ExportOptions.fileName(fileName.fileNamePrefix)
        val basicOptions = TableOptions
          .data(rs("array"))
          .columns(columns)
          .exportOptions(exportOptions)
          .showExport(true)
          .exportDataType("all")
          .exportTypes(js.Array("csv"))
          .pagination(true)
          .pageList(js.Array("10", "25", "50", "100", "all"))
          .locale(Tool.getBTLanguage)
        val options = if (columnNames.isEmpty) {
          basicOptions.showHeader(false)
        } else basicOptions
        $(s"#${modalId} #${tableId}").bootstrapTable("destroy").bootstrapTable(options)
      }
  }

}
